/**
 * 练习：操作GPIO
 * 引脚：输出：IO18、IO19
 *      输入：IO4、IO5
 * 中断：IO4：上升沿、下降沿；
 *      IO5：下降沿；
 * 创建时间：2024/8/13
*/

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "driver/gpio.h"

/*宏定义*/
#define GPIO_OUT_PIN_0     GPIO_NUM_18
#define GPIO_OUT_PIN_1     GPIO_NUM_19
#define GPIO_IN_PIN_0      GPIO_NUM_4
#define GPIO_IN_PIN_1      GPIO_NUM_5 

#define EVENT_INTR_0       BIT0
#define EVENT_INTR_1       BIT1

/*全局变量、句柄*/
EventGroupHandle_t gpio_eventgroup_handle;


/*任务函数、回调函数*/
static void IRAM_ATTR isr_handler(void* argument){
    uint32_t gpio_num = (uint32_t)(argument);
    BaseType_t taskWaken;
    if(gpio_num == GPIO_IN_PIN_0)
        xEventGroupSetBitsFromISR(gpio_eventgroup_handle, EVENT_INTR_0, &taskWaken);
    else if(gpio_num == GPIO_IN_PIN_1)
        xEventGroupSetBitsFromISR(gpio_eventgroup_handle, EVENT_INTR_1, &taskWaken);
}

static void gpio_task(void* arg){
    EventBits_t bit_get;
    while(1){
        bit_get = xEventGroupWaitBits(gpio_eventgroup_handle, EVENT_INTR_0|EVENT_INTR_1, pdTRUE, pdFALSE, portMAX_DELAY);
        if(bit_get & EVENT_INTR_0){
            printf("From GPIO[4], val:%d\n", gpio_get_level(GPIO_NUM_4));
        }
        else if(bit_get & EVENT_INTR_1){
            printf("From GPIO[5], val:%d\n", gpio_get_level(GPIO_NUM_5));
        }
    }
}

void app_main(void)
{
    /*IO结构体配置*/
    gpio_config_t io_config = {
        .pin_bit_mask = (1<<GPIO_OUT_PIN_0)|(1<<GPIO_OUT_PIN_1),
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_DISABLE,
    };
    gpio_config(&io_config);
    
    io_config.pin_bit_mask = (1<<GPIO_IN_PIN_0)|(1<<GPIO_IN_PIN_1);
    io_config.mode = GPIO_MODE_INPUT;
    io_config.pull_up_en = GPIO_PULLUP_ENABLE;
    io_config.intr_type = GPIO_INTR_POSEDGE;//下降沿
    gpio_config(&io_config);

    gpio_set_intr_type(GPIO_IN_PIN_0, GPIO_INTR_ANYEDGE);//任意沿
    /*事件组创建*/
    gpio_eventgroup_handle = xEventGroupCreate();

    /*中断配置*/
    gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
    gpio_isr_handler_add(GPIO_IN_PIN_0, isr_handler, (void*)GPIO_IN_PIN_0);
    gpio_isr_handler_add(GPIO_IN_PIN_1, isr_handler, (void*)GPIO_IN_PIN_1);

    /*创建接收任务*/
    xTaskCreatePinnedToCore(&gpio_task, "gpio_task", 2048, NULL, 4, NULL, APP_CPU_NUM);

    uint32_t cnt = 0;
    while (1){
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        gpio_set_level(GPIO_NUM_18, cnt%2);
        gpio_set_level(GPIO_NUM_19, cnt%2);
        cnt++;    
    }
    
}
